

function useStorageManager<T = string>(key: string, equal?: (a: T, b: T) => boolean) {
  if (!localStorage.getItem(key)) {
    localStorage.setItem(key, JSON.stringify([]))
  }

  let data: T[] = JSON.parse(localStorage.getItem(key) || '[]')

  function setData(newData: T[]) {
    localStorage.setItem(key, JSON.stringify(newData))
    data = newData
  }

  function getData() {
    return data
  }

  function addItem(item: T) {
    const res = data.find((v) => (equal ? equal(v, item) : v === item))
    if (res) {
      updateItem(res, item)
      return
    }
    const newData = [...data, item]
    setData(newData)
  }

  function removeItem(item: T) {
    if (equal) {
      const newData = data.filter((v) => !equal(v, item))
      setData(newData)
    } else {
      setData(data.filter((v) => v !== item))
    }
  }

  function updateItem(item: T, update: Partial<T>) {
    const newData = data.map((v) => (equal ? equal(v, item) : v === item) ? { ...v, ...update } : v)
    setData(newData)
  }

  function getItem(item: T) {
    if (equal) {
      return data.find((v) => equal(v, item))
    }
    return data.find((v) => v === item)
  }

  function getItems() {
    return data
  }

  return {
    addItem,
    removeItem,
    updateItem,
    getItem,
    getItems
  }
}

export default useStorageManager